// Common features for ease-of-use
//--------------------------------
#ifndef COMMON_H
#define COMMON_H
#include "forward.h"

#include <vector>
#include <set>
#include <string>
#include <boost/foreach.hpp>

typedef unsigned int  uint;
typedef unsigned char uchar;
#define foreach       BOOST_FOREACH
#define SELF          ( *this )

class QuitException : public std::exception { };

class ustring : public std::basic_string< uchar > {
public:
    typedef std::basic_string< uchar > bstring;

    ustring() { }
    virtual ~ustring() { }
    ustring( const ustring& s ) : bstring( s ) { }
    ustring( const bstring& s ) : bstring( s ) { }
    ustring( const std::string& s )
    {
        for ( uint i = 0; i < s.length(); i++ )
            bstring::operator+=( uchar( s[ i ] ) );
    }
    ustring( char c )
    {
        bstring::operator+=( uchar( c ) );
    }
    ustring( uchar c )
    {
        bstring::operator+=( c );
    }
    ustring( uint count, char c )
    {
        for ( uint i = 0; i < count; ++i )
            bstring::operator+=( uchar( c ) );
    }
    ustring( uint count, uchar c )
    {
        for ( uint i = 0; i < count; ++i )
            bstring::operator+=( c );
    }
};

typedef std::vector< Tile >                  TileList;
typedef std::vector<       Actor*   >        ActorList;
typedef std::vector< const Actor*   >   ConstActorList;
typedef std::vector<       Buff*    >         BuffList;
typedef std::vector< const Buff*    >    ConstBuffList;
typedef std::vector<       Item*    >         ItemList;
typedef std::vector< const Item*    >    ConstItemList;
typedef std::vector<       Behaved* >      BehavedList;
typedef std::vector< const Behaved* > ConstBehavedList;
typedef std::set<        Buff* >       BuffSet;
typedef std::set<       Actor* >      ActorSet;
typedef std::set<        Item* >       ItemSet;
typedef std::set<  const Buff* >  ConstBuffSet;
typedef std::set< const Actor* > ConstActorSet;
typedef std::set<  const Item* >  ConstItemSet;

class ActorPrioritySorter {
public:
    bool operator()( const Actor* less, const Actor* greater ) const;
};

class BuffPrioritySorter {
public:
    bool operator()( const Buff* less, const Buff* greater ) const;
};

class ItemPrioritySorter {
public:
    bool operator()( const Item* less, const Item* greater ) const;
};

struct Colour {
    Colour( uchar red = 0, uchar green = 0, uchar blue = 0 )
    : r( red ), g( green ), b( blue ) { }

    uchar r;
    uchar g;
    uchar b;
};

enum NameArticle {
    ARTICLE_NONE,
    ARTICLE_INDEFINITE,
    ARTICLE_PLURAL
};

uint GetDirection( uint in );

#endif
